#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import threading
from typing import Optional
import wintun
from logger import logger
from network import NetworkManager
from config import config

class VPNTunnel:
    def __init__(self, network_manager: NetworkManager):
        self.network_manager = network_manager
        self.tun = None
        self.running = False
        self.read_thread = None
        self.setup_tunnel()

    def setup_tunnel(self) -> None:
        """设置VPN隧道"""
        try:
            # 创建Wintun适配器
            adapter = wintun.Adapter()
            self.tun = adapter.create_interface('p2p_vpn')
            # 配置IP地址和路由
            virtual_ip = config.get('virtual_ip')
            remote_ip = config.get('remote_node', {}).get('virtual_ip')
            self.tun.set_ip(virtual_ip)
            self.tun.add_route(remote_ip)
            
            # 注册网络消息处理器
            self.network_manager.register_handler('VPN_DATA', self._handle_vpn_data)
            logger.info(f'VPN隧道设置完成，虚拟IP: {self.tun.addr}')
        except Exception as e:
            logger.error(f'设置VPN隧道失败: {e}')
            raise

    def start(self) -> None:
        """启动VPN隧道"""
        if not self.tun:
            logger.error('VPN隧道未设置')
            return

        self.running = True
        self.read_thread = threading.Thread(target=self._read_tunnel)
        self.read_thread.daemon = True
        self.read_thread.start()
        logger.info('VPN隧道启动')

    def stop(self) -> None:
        """停止VPN隧道"""
        self.running = False
        if self.tun:
            self.tun.delete()
        if self.read_thread:
            self.read_thread.join()
        logger.info('VPN隧道停止')

    def _read_tunnel(self) -> None:
        """从Wintun接口读取数据并发送到远程节点"""
        while self.running:
            try:
                data = self.tun.receive_packet()
                if data:
                    # 发送数据到远程节点
                    self.network_manager.send_message('VPN_DATA', data)
            except Exception as e:
                if self.running:
                    logger.error(f'读取Wintun接口数据失败: {e}')

    def _handle_vpn_data(self, data: bytes, addr: tuple) -> None:
        """处理从远程节点接收到的VPN数据"""
        try:
            if self.tun and data:
                self.tun.send_packet(data)
        except Exception as e:
            logger.error(f'写入Wintun接口数据失败: {e}')

    def get_tunnel_info(self) -> dict:
        """获取隧道信息"""
        if not self.tun:
            return {}
        return {
            'name': self.tun.name,
            'running': self.running
        }